#include "gkt_rtc.h"
#include "gkt_version.h"
#include "window_common.h"
#include "string.h"
#include "gkt_os.h"

#define	YEARMAX	2064
#define	HOURMAX	GKT_DT_DAY_HOURS
#define MINMAX	GKT_DT_HOUR_MINUTES
#define	SECMAX	GKT_DT_MINUTE_SECONDS

#define SYSTEM_RTC_WAIT_TIME	2000

const char mon_day[2][12] = {\
		{31,28,31,30,31,30,31,31,30,31,30,31},
		{31,29,31,30,31,30,31,31,30,31,30,31}
		};

static gkt_date_time_s s_system_time_date = GKT_DATE_TIME(GKT_WINDOW_DATE_YEAR_DEFAULT, 1, 1, 8, 0, 0);
static gkt_date_time_s date_time_temp;

enum {
	RETVAL_CONRINUE = 0,
	RETVAL_EPARAM,
	RETVAL_COMPLETE,
	RETVAL_MAX
};

enum {
	WIDGET_ID_TITLE = 0,

	WIDGET_ID_DATE,
	WIDGET_ID_YEAR,
	WIDGET_ID_SEPARATOR1,
	WIDGET_ID_MONTH,
	WIDGET_ID_SEPARATOR2,
	WIDGET_ID_DAY,

	WIDGET_ID_TIME,
	WIDGET_ID_HOUR,
	WIDGET_ID_SEPARATOR3,
	WIDGET_ID_MIN,
	WIDGET_ID_SEPARATOR4,
	WIDGET_ID_SEC,

	WIDGET_ID_HINT,
	WIDGET_ID_OK_CANCEL,
	WIDGET_ID_MAX
};

enum {
	WINDOW_SYSTEM_TIME_TIMER_WAIT_STABLE = 0,
	WINDOW_SYSTEM_TIME_TIMER_MAX
};

GKT_WINDOW_WIDGET_DESCS_DEFINE(system_time_setting) = {
	[WIDGET_ID_TITLE] = GKT_WIDGET_LABEL_DESC( 
		GKT_WIDGET_F_ALIGN_MIDDLE | GKT_WIDGET_F_TITLE_MARK,
		WINDOW_FONT_NORMAL_SIZE, 
		WINDOW_TITLE_FG_COLOR, WINDOW_TITLE_BG_COLOR,
		0, 0, WINDOW_WIDGET_DEFAULT_WIDTH, 
		WINDOW_FONT_NORMAL_SIZE + 2,
		WINDOW_TEXT_ID_system_time
	),
	[WIDGET_ID_DATE] = GKT_WIDGET_LABEL_DESC( 
		GKT_WIDGET_F_ALIGN_MIDDLE,
		WINDOW_FONT_NORMAL_SIZE, WINDOW_DEFAULT_FG_COLOR, WINDOW_DEFAULT_BG_COLOR,
		0, WINDOW_FONT_NORMAL_SIZE + 2, 
		WINDOW_FONT_NORMAL_SIZE * 2 + 8, 
		WINDOW_FONT_NORMAL_SIZE + 2,
		WINDOW_TEXT_ID_date
	),
	[WIDGET_ID_YEAR] = GKT_WIDGET_INPUTBOX_TEXT_DESC(
		GKT_WIDGET_F_FOCUS | GKT_WIDGET_F_ALIGN_MIDDLE,
		WINDOW_FONT_NORMAL_SIZE,
		WINDOW_FONT_NORMAL_SIZE * 2 + 8,
		WINDOW_FONT_NORMAL_SIZE + 2,
		WINDOW_FONT_NORMAL_SIZE * 2 + 2 + 2,
		WINDOW_FONT_NORMAL_SIZE + 2,
		4, 4
	),
	[WIDGET_ID_SEPARATOR1] = GKT_WIDGET_LABEL_DESC(
		GKT_WIDGET_F_ALIGN_MIDDLE,
		WINDOW_FONT_NORMAL_SIZE, WINDOW_DEFAULT_FG_COLOR, WINDOW_DEFAULT_BG_COLOR,
		WINDOW_FONT_NORMAL_SIZE * 4 + GKT_WIDGET_BORDER_WIDTH * 2 + 10,
		WINDOW_FONT_NORMAL_SIZE + GKT_WIDGET_BORDER_WIDTH * 2,
		WINDOW_FONT_NORMAL_SIZE - 2,
		WINDOW_FONT_NORMAL_SIZE + GKT_WIDGET_BORDER_WIDTH * 2,
		"-"
	),	
	[WIDGET_ID_MONTH] = GKT_WIDGET_INPUTBOX_TEXT_DESC(
		GKT_WIDGET_F_ALIGN_MIDDLE,
		WINDOW_FONT_NORMAL_SIZE,
		WINDOW_FONT_NORMAL_SIZE * 5 + 10, 
		WINDOW_FONT_NORMAL_SIZE + GKT_WIDGET_BORDER_WIDTH * 2,
		WINDOW_FONT_NORMAL_SIZE + GKT_WIDGET_BORDER_WIDTH * 2 + 2,
		WINDOW_FONT_NORMAL_SIZE + GKT_WIDGET_BORDER_WIDTH * 2,
		1, 2
	),
	[WIDGET_ID_SEPARATOR2] = GKT_WIDGET_LABEL_DESC( 
		GKT_WIDGET_F_ALIGN_MIDDLE,
		WINDOW_FONT_NORMAL_SIZE, WINDOW_DEFAULT_FG_COLOR, WINDOW_DEFAULT_BG_COLOR,
		WINDOW_FONT_NORMAL_SIZE * 6 + GKT_WIDGET_BORDER_WIDTH * 2 + 12, 
		WINDOW_FONT_NORMAL_SIZE + GKT_WIDGET_BORDER_WIDTH * 2,
		WINDOW_FONT_NORMAL_SIZE - 2,
		WINDOW_FONT_NORMAL_SIZE + GKT_WIDGET_BORDER_WIDTH * 2,
		"-"
	),	
	[WIDGET_ID_DAY] = GKT_WIDGET_INPUTBOX_TEXT_DESC(
		GKT_WIDGET_F_ALIGN_MIDDLE,
		WINDOW_FONT_NORMAL_SIZE,
		WINDOW_FONT_NORMAL_SIZE * 7 + 12,  
		WINDOW_FONT_NORMAL_SIZE + 2,
		WINDOW_FONT_NORMAL_SIZE + 4,
		WINDOW_FONT_NORMAL_SIZE + 2,
		1, 2
	),

	[WIDGET_ID_TIME] = GKT_WIDGET_LABEL_DESC( 
		GKT_WIDGET_F_ALIGN_MIDDLE,
		WINDOW_FONT_NORMAL_SIZE, WINDOW_DEFAULT_FG_COLOR, WINDOW_DEFAULT_BG_COLOR,
		0, (WINDOW_FONT_NORMAL_SIZE + 2) * 2,
		WINDOW_FONT_NORMAL_SIZE * 2 + 8,
		WINDOW_FONT_NORMAL_SIZE + 2,
		WINDOW_TEXT_ID_time
	),
	[WIDGET_ID_HOUR] = GKT_WIDGET_INPUTBOX_TEXT_DESC(
		GKT_WIDGET_F_ALIGN_MIDDLE,
		WINDOW_FONT_NORMAL_SIZE,
		WINDOW_FONT_NORMAL_SIZE * 2 + 8,
		(WINDOW_FONT_NORMAL_SIZE + 2) * 2,
		WINDOW_FONT_NORMAL_SIZE + 4,
		WINDOW_FONT_NORMAL_SIZE + GKT_WIDGET_BORDER_WIDTH * 2,
		1, 2
	),
	[WIDGET_ID_SEPARATOR3] = GKT_WIDGET_LABEL_DESC( 
		GKT_WIDGET_F_ALIGN_MIDDLE,
		WINDOW_FONT_NORMAL_SIZE, WINDOW_DEFAULT_FG_COLOR, WINDOW_DEFAULT_BG_COLOR,
		WINDOW_FONT_NORMAL_SIZE * 3 + 12,
		(WINDOW_FONT_NORMAL_SIZE + 2) * 2,
		WINDOW_FONT_NORMAL_SIZE - GKT_WIDGET_BORDER_WIDTH * 2,
		WINDOW_FONT_NORMAL_SIZE + GKT_WIDGET_BORDER_WIDTH * 2,
		":"
	),	
	[WIDGET_ID_MIN] = GKT_WIDGET_INPUTBOX_TEXT_DESC(
		GKT_WIDGET_F_ALIGN_MIDDLE,
		WINDOW_FONT_NORMAL_SIZE,
		WINDOW_FONT_NORMAL_SIZE * 4 + 10, 
		(WINDOW_FONT_NORMAL_SIZE + 2) * 2,
		WINDOW_FONT_NORMAL_SIZE + 4,
		WINDOW_FONT_NORMAL_SIZE + GKT_WIDGET_BORDER_WIDTH * 2,
		1, 2
	),
	[WIDGET_ID_SEPARATOR4] = GKT_WIDGET_LABEL_DESC( 
		GKT_WIDGET_F_ALIGN_MIDDLE,
		WINDOW_FONT_NORMAL_SIZE, WINDOW_DEFAULT_FG_COLOR, WINDOW_DEFAULT_BG_COLOR,
		WINDOW_FONT_NORMAL_SIZE * 5 + 14, 
		(WINDOW_FONT_NORMAL_SIZE + 2) * 2,
		WINDOW_FONT_NORMAL_SIZE - GKT_WIDGET_BORDER_WIDTH * 2,
		WINDOW_FONT_NORMAL_SIZE + GKT_WIDGET_BORDER_WIDTH * 2,
		":"
	),	
	[WIDGET_ID_SEC] = GKT_WIDGET_INPUTBOX_TEXT_DESC(
		GKT_WIDGET_F_ALIGN_MIDDLE,
		WINDOW_FONT_NORMAL_SIZE,
		WINDOW_FONT_NORMAL_SIZE * 6 + 12,
		(WINDOW_FONT_NORMAL_SIZE + GKT_WIDGET_BORDER_WIDTH * 2) * 2,
		WINDOW_FONT_NORMAL_SIZE + 4,
		WINDOW_FONT_NORMAL_SIZE + GKT_WIDGET_BORDER_WIDTH * 2,
		1, 2
	),

	[WIDGET_ID_HINT] = GKT_WIDGET_LABEL_DESC( 
		GKT_WIDGET_F_ALIGN_MIDDLE,
		WINDOW_FONT_NORMAL_SIZE, WINDOW_DEFAULT_FG_COLOR, WINDOW_DEFAULT_BG_COLOR,
		0, (WINDOW_FONT_NORMAL_SIZE + 2) * 2,
		WINDOW_WIDGET_DEFAULT_WIDTH, WINDOW_FONT_NORMAL_SIZE + GKT_WIDGET_BORDER_WIDTH * 2,
		WINDOW_TEXT_ID_seting_and_wait
	),
	[WIDGET_ID_OK_CANCEL] = GKT_WIDGET_LABEL_DESC( 
		GKT_WIDGET_F_ALIGN_MIDDLE,
		WINDOW_FONT_NORMAL_SIZE, WINDOW_DEFAULT_FG_COLOR, WINDOW_DEFAULT_BG_COLOR,
		0, (WINDOW_FONT_NORMAL_SIZE + GKT_WIDGET_BORDER_WIDTH * 2) * 3,
		WINDOW_WIDGET_DEFAULT_WIDTH, WINDOW_FONT_NORMAL_SIZE + GKT_WIDGET_BORDER_WIDTH * 2,
		WINDOW_TEXT_ID_cancel_ok
	),
};

static uint32_t window_system_time_setting_to_dec(gkt_widget_inputbox_data_s *textbox_data)
{
	uint32_t temp_data=0;
	int i=0;
	gkt_widget_inputbox_data_s *p;
	p=textbox_data;
	while(i<(p->size)){
		temp_data *= 10;
		temp_data += (p->data[i]-'0');
		i++;
	}
	return temp_data;
}

static void window_system_time_setting_dec_to_char(uint32_t dec,gkt_widget_inputbox_data_s *textbox_data)
{
	char temp_data[4] = {'0','0','0','0'};
	int i=0;
	
	while(dec){
		temp_data[4-i-1] = (dec%10)+'0';
		dec /= 10;
		i++;
	}
	if(i<2)
		i = 2;
	memcpy(textbox_data->data,temp_data+4-i,i);
	textbox_data->size = i;
	textbox_data->focus_index = 0;
}
//DATE FUNCTION
static int window_system_time_data_handle(gkt_widget_id_t widget_id,
														gkt_date_time_s *input_date,uint32_t num,
															gkt_widget_inputbox_data_s *event_data)
{
	uint8_t retval = RETVAL_CONRINUE;
	if(widget_id == WIDGET_ID_YEAR){
		if(num < YEARMAX && num >= GKT_DT_YEAR_BASE){
			input_date->date.year = num;
			gkt_widget_set_focus_by_id(WIDGET_ID_MONTH);
		}
		else{
			event_data->focus_index = 0;
			gkt_widget_set_data_by_id(WIDGET_ID_YEAR,(uint32_t)event_data);
			retval = RETVAL_EPARAM;
		}
	}
	else if(widget_id == WIDGET_ID_MONTH){
		if(num <= GKT_DT_MONTH_DEC && num >= GKT_DT_MONTH_JAN){
			input_date->date.month = num;
			gkt_widget_set_focus_by_id(WIDGET_ID_DAY);
		}
		else{
			event_data->focus_index = 0;
			gkt_widget_set_data_by_id(WIDGET_ID_MONTH,(uint32_t)event_data);
			retval = RETVAL_EPARAM;
		}
	}
	else if(widget_id == WIDGET_ID_DAY){
		if((input_date->date.year%4==0&&input_date->date.year%100 != 0)
				|| (input_date->date.year%400 == 0)){	//
			if((num <= mon_day[1][input_date->date.month-1]) && (num > 0)){
				input_date->date.day = num;
				gkt_widget_set_focus_by_id(WIDGET_ID_HOUR);
			}
			else{
				event_data->focus_index = 0;
				gkt_widget_set_data_by_id(WIDGET_ID_DAY,(uint32_t)event_data);
				retval = RETVAL_EPARAM;
			}
		}
		else{
			if((num <= mon_day[0][input_date->date.month-1]) && (num > 0)){
				input_date->date.day = num;
				gkt_widget_set_focus_by_id(WIDGET_ID_HOUR);
			}
			else{
				event_data->focus_index = 0;
				gkt_widget_set_data_by_id(WIDGET_ID_DAY,(uint32_t)event_data);
				retval = RETVAL_EPARAM;
			}
		}
	}
	else if(widget_id == WIDGET_ID_HOUR){
		if(num < HOURMAX){
			input_date->time.hour = num;
			gkt_widget_set_focus_by_id(WIDGET_ID_MIN);
		}
		else{
			event_data->focus_index = 0;
			gkt_widget_set_data_by_id(WIDGET_ID_HOUR,(uint32_t)event_data);
			retval = RETVAL_EPARAM;
		}
	}
	else if(widget_id == WIDGET_ID_MIN){
		if(num < MINMAX){
			input_date->time.minute = num;
			gkt_widget_set_focus_by_id(WIDGET_ID_SEC);
		}
		else{
			event_data->focus_index = 0;
			gkt_widget_set_data_by_id(WIDGET_ID_MIN,(uint32_t)event_data);
			retval = RETVAL_EPARAM;
		}
	}
	else if(widget_id == WIDGET_ID_SEC){
		if(num < SECMAX){
			input_date->time.second = num;
			retval = RETVAL_COMPLETE;
		}
		else{
			event_data->focus_index = 0;
			gkt_widget_set_data_by_id(WIDGET_ID_SEC,(uint32_t)event_data);
			retval = RETVAL_EPARAM;
		}
	}
	return retval;
}

static void window_system_time_setting_set_date(gkt_date_u input_date)
{
	gkt_widget_inputbox_data_s date;

	if(input_date.year < s_system_time_date.date.year)
		input_date.year = s_system_time_date.date.year;
	window_system_time_setting_dec_to_char(input_date.year,&date);
	date.focus_index = 2;
	gkt_widget_set_data_by_id(WIDGET_ID_YEAR,(uint32_t)&date);
	
	window_system_time_setting_dec_to_char(input_date.month,&date);
	gkt_widget_set_data_by_id(WIDGET_ID_MONTH,(uint32_t)&date);
	
	window_system_time_setting_dec_to_char(input_date.day,&date);
	gkt_widget_set_data_by_id(WIDGET_ID_DAY,(uint32_t)&date);
}

static void window_system_time_setting_set_time(gkt_time_u input_time)
{
	gkt_widget_inputbox_data_s time;
	
	window_system_time_setting_dec_to_char(input_time.hour,&time);
	gkt_widget_set_data_by_id(WIDGET_ID_HOUR,(uint32_t)&time);
	
	window_system_time_setting_dec_to_char(input_time.minute,&time);
	gkt_widget_set_data_by_id(WIDGET_ID_MIN,(uint32_t)&time);
	
	window_system_time_setting_dec_to_char(input_time.second,&time);
	gkt_widget_set_data_by_id(WIDGET_ID_SEC,(uint32_t)&time);
}

static void window_system_time_setting_timer_handle(void)
{
	uint32_t hint_type, hint_text_id, voice_id;

	hint_type = WINDOW_DIALOG_HINT_SUCCESS;
	hint_text_id = WINDOW_TEXT_ID_set_success;
	voice_id = WINDOW_VOICE_COMBINED_ID(set_success);
	window_dialog_show_big_prompt(hint_type,
		WINDOW_TEXT_ID_system_time, hint_text_id, voice_id);
	
	gkt_window_exit();
}

void window_system_time_click_handle(gkt_widget_id_t widget_id,
														gkt_date_time_s *input_date,uint32_t num,
															gkt_widget_inputbox_data_s *event_data)
{
	uint32_t i, hint_type, hint_text_id, voice_id;
	int retval;

	retval = window_system_time_data_handle(widget_id,input_date,num,event_data);
	if(retval == RETVAL_COMPLETE){
		window_common_mask_all();
		for(i=WIDGET_ID_TITLE + 1; i<WIDGET_ID_MAX;i++)
			gkt_widget_hide_by_id(i);
		gkt_widget_set_showable_by_id(WIDGET_ID_HINT, 1);
		gkt_widget_show_by_id(WIDGET_ID_HINT);

		retval = gkt_rtc_set_time(input_date);
		if(retval == GKT_SUCCESS) {
			retval = gkt_window_timer_set(WINDOW_SYSTEM_TIME_TIMER_WAIT_STABLE,SYSTEM_RTC_WAIT_TIME,0,0);
			if (GKT_SUCCESS == retval){
				return;
			}
			else{
				gkt_thread_sleep(SYSTEM_RTC_WAIT_TIME); //wait rtc stable
			}
			hint_type = WINDOW_DIALOG_HINT_SUCCESS;
			hint_text_id = WINDOW_TEXT_ID_set_success;
			voice_id = WINDOW_VOICE_COMBINED_ID(set_success);			
		}
		else{
			hint_type = WINDOW_DIALOG_HINT_FAILED;
			hint_text_id = WINDOW_TEXT_ID_set_fail;
			voice_id = WINDOW_VOICE_COMBINED_ID(set_failed);		
		}
		window_dialog_show_big_prompt(hint_type,
			WINDOW_TEXT_ID_system_time, hint_text_id, voice_id);

		gkt_window_exit();
	}
}

//event handler
static int window_system_time_setting_event_handler(
				uint32_t major_type, uint32_t minor_type, 
				uint32_t widget_id, uint32_t data)
{
	int retval = GKT_EVENT_HANDLE_CONTINUE,result;
	uint32_t num;

	switch (major_type) {
		case GKT_EVENT_WINDOW:
			if(GKT_WINDOW_ACTIVE == minor_type) {
				gkt_widget_set_showable_by_id(WIDGET_ID_HINT, 0);
				window_common_mask_except_keys(~0);

				if (data) {
					gkt_window_set_voice(WINDOW_VOICE_COMBINED_ID(please_input_system_date_time),
						GKT_WINDOW_VOICE_F_NOTIFY_END | GKT_WINDOW_VOICE_F_NOTIFY_ERROR);
				}

				result = gkt_rtc_get_time(&date_time_temp);
				if(result == GKT_SUCCESS){
					window_system_time_setting_set_date(date_time_temp.date);
					window_system_time_setting_set_time(date_time_temp.time);
				}
				else{
					memcpy((uint8_t *)&date_time_temp,(uint8_t *)&s_system_time_date,sizeof(gkt_date_time_s));
					window_system_time_setting_set_date(s_system_time_date.date);
					window_system_time_setting_set_time(s_system_time_date.time);
				}
			}
			break;
		case GKT_EVENT_WIDGET:
			if(minor_type == GKT_WIDGET_EVENT_DATA_FULL){
				gkt_widget_inputbox_data_s *event_data;
				event_data = (gkt_widget_inputbox_data_s *)data;
				num = window_system_time_setting_to_dec(event_data);
				window_system_time_data_handle(widget_id,&date_time_temp,num,event_data);
				retval = GKT_EVENT_HANDLE_COMPLETE;
			}
			else if(minor_type == GKT_WIDGET_EVENT_CLICK){//
				gkt_widget_inputbox_data_s *event_data;
				event_data = (gkt_widget_inputbox_data_s *)data;
				num = window_system_time_setting_to_dec(event_data);
				window_system_time_click_handle(widget_id,&date_time_temp,num,event_data);
				retval = GKT_EVENT_HANDLE_COMPLETE;
			}
			else if(minor_type == GKT_WIDGET_EVENT_HEAD){
				if(widget_id == WIDGET_ID_MONTH){
					gkt_widget_set_focus_by_id(WIDGET_ID_YEAR);
					retval = GKT_EVENT_HANDLE_STAGE;
				}
				else if(widget_id == WIDGET_ID_DAY){
					gkt_widget_set_focus_by_id(WIDGET_ID_MONTH);
					retval = GKT_EVENT_HANDLE_STAGE;
				}				
				else if(widget_id == WIDGET_ID_HOUR){
					gkt_widget_set_focus_by_id(WIDGET_ID_DAY);
					retval = GKT_EVENT_HANDLE_STAGE;
				}
				else if(widget_id == WIDGET_ID_MIN){
					gkt_widget_set_focus_by_id(WIDGET_ID_HOUR);
					retval = GKT_EVENT_HANDLE_STAGE;
				}
				else if(widget_id == WIDGET_ID_SEC){
					gkt_widget_set_focus_by_id(WIDGET_ID_MIN);
					retval = GKT_EVENT_HANDLE_STAGE;
				}
				else{
					gkt_window_exit();
				}
			}
			break;
		case GKT_EVENT_TIMER:
			gkt_window_timer_clear(WINDOW_SYSTEM_TIME_TIMER_WAIT_STABLE);
			window_system_time_setting_timer_handle();
			retval = GKT_EVENT_HANDLE_COMPLETE;
			break;
		default:
			break;
	}
	
	return retval;
}


GKT_WINDOW_DESC_DEFINE(system_time_setting);

